package com.lagou.v4.coyote;

import com.lagou.thread.RequestProcessor;
import com.lagou.v4.LifeCycle;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author Kirito
 * @description:
 * @date 2020/05/03
 */
public class EndPoint implements LifeCycle {

    private Integer port;

    private ServerSocket serverSocket;

    private Socket socket;

    private CoyoteAdaptor adaptor;

    public CoyoteAdaptor getAdaptor() {
        return adaptor;
    }

    public void setAdaptor(CoyoteAdaptor adaptor) {
        this.adaptor = adaptor;
    }

    public Integer getPort() {
        return port;
    }

    public void setPort(Integer port) {
        this.port = port;
    }

    @Override
    public void init() throws Exception {
        bind();
    }

    @Override
    public void start() throws Exception {

        while (true) {
            Socket socket = serverSocket.accept();
            RequestProcessor processor = new RequestProcessor(socket, adaptor);
            getExecutor().execute(processor);
        }

    }

    private Executor getExecutor() {
        // 定义⼀个线程池
        int corePoolSize = 5;
        int maximumPoolSize = 20;
        long keepAliveTime = 100L;
        TimeUnit unit = TimeUnit.SECONDS;
        BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(20);
        ThreadFactory threadFactory = Executors.defaultThreadFactory();
        RejectedExecutionHandler handler = new
                ThreadPoolExecutor.AbortPolicy();
        return new ThreadPoolExecutor(
                corePoolSize,
                maximumPoolSize,
                keepAliveTime,
                unit,
                workQueue,
                threadFactory,
                handler
        );
    }

    /**
     * 绑定Socket监听端口
     *
     * @throws IOException IOException
     */
    private void bind() throws IOException {
        serverSocket = new ServerSocket(port);
    }

}
